from client.unitsystem.unit import Unit
from client.utils.postring import Postring
from panda3d.core import VBase3, Vec3
from pandac.PandaModules import TransparencyAttrib, ColorBlendAttrib
import __builtin__
import database.units

from networking.ganet.network import message


class UnitManager:

    def __init__(self, game):
        self.unitNode = __builtin__.render.attachNewNode("Unit Node")
        self.target = __builtin__.loader.loadModel("client/models/ground6")
        self.target.setTransparency(TransparencyAttrib.MBinary, 1)
        #self.target.setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingAlpha, ColorBlendAttrib.OOne))
        #self.target.setAlphaScale(0.5)
        #self.target.setDepthWrite(False)
        self.target.setZ(0.05)
        #self.target.setScale(0.004, 0.004, 0.004)
        self.target.reparentTo(__builtin__.render)
        self.target.detachNode()
        self.unitNode.detachNode()
        self.game = game
        self.placeable = 1
        self.counter = 1
        self.coll_counter = 0
        self.unitcursor = None
        self.units = []
        self.warpzones = []
        return

    def activate(self):
        self.unitNode =__builtin__.render.attachNewNode("Unit Node")
        self.target.reparentTo(__builtin__.render)
        self.prepare_cursor("Knockknockbot")
        self.unitcursor.detach_node()

    def deactivate(self):
        self.destroy_units()
        self.destroy_warpzones()
        self.unitNode.remove_node()
        self.target.detachNode()
        self.unitcursor.remove_node()
        self.unitcursor = None

    def update_mouse(self, x, y, z):
        self.unitcursor.setPos(Vec3(x, y, z))
        self.unitcursor.reface()

    def update(self, tpf):
        for unit in self.units:
            unit.update(tpf)

    def update_placementcheck(self):
        self.placeable = 1
        if VBase3.length(self.unitcursor.getposition()) < 15 or VBase3.length(self.unitcursor.getposition()) > 26:
            self.placeable = 0
        else:
            for u in self.units:
                if u.radius+self.unitcursor.radius > VBase3.length(u.getposition()-self.unitcursor.getposition()):
                    self.placeable = 0
        if self.unitcursor.name != "warpzone":
            if len(self.warpzones) == 0:
                self.placeable = 0
            inthezone = 0
            for w in self.warpzones:
                dis = w.getposition() - self.unitcursor.getposition()
                if VBase3.length(dis) <= w.speed:
                    inthezone = 1
            if not inthezone:
                self.placeable = 0

        if self.placeable and self.game.curMoney >= self.unitcursor.cost:
            self.unitcursor.unit_object.setColor(1, 1, 1, 0.5)
        else:
            self.unitcursor.unit_object.setColor(1, 0, 0, 0.75)

    def request_selection(self, pos):
        enc = __builtin__.base.gamestatemanager.getState("RunningSession").prep_msg("select")
        enc.write_float(pos[0])
        enc.write_float(pos[1])
        __builtin__.base.gamestatemanager.getState("RunningSession").send_message(enc.get_message())

    def request_unit_placement(self, pos):
        name = self.unitcursor.name
        enc = __builtin__.base.gamestatemanager.getState("RunningSession").prep_msg("place_unit")
        enc.write_string(name)
        enc.write_float(pos[0])
        enc.write_float(pos[1])
        __builtin__.base.gamestatemanager.getState("RunningSession").send_message(enc.get_message())

    def request_warpzone_placement(self, pos):
        enc = __builtin__.base.gamestatemanager.getState("RunningSession").prep_msg("place_warpzone")
        enc.write_float(pos[0])
        enc.write_float(pos[1])
        __builtin__.base.gamestatemanager.getState("RunningSession").send_message(enc.get_message())


    def place_unit(self, name, pos):
        print pos[0]
        self.game.select_unit(self.build_unit(name, pos))
        self.game.canBuild = 0
        self.remove_cursor()
        #print("Placed " + t.name + " at " + str(t.towerNode.getPos()))

    def place_warpzone(self, pos):
        u = database.units.create_client_unit("warpzone")
        u.setPos(Vec3(pos[0], pos[1], 0))
        u.reparentTo(__builtin__.render)
        u.model.play("land")
        self.warpzones.append(u)
        self.game.placewarpzone = 0
        self.remove_cursor()

    def build_unit(self, name, center):
        u = None
        for x in range(0, 1):
            u = database.units.create_client_unit(name)
            u.movetowards(Vec3(center[0], center[1], 0))
            u.reparentTo(self.unitNode)
            u.set_destination(0, 0)
            self.units.append(u)
        return u

    def request_upgrade(self, unit, x):
        index = self.units.index(unit)
        enc = __builtin__.base.gamestatemanager.getState("RunningSession").prep_msg("upgrade")
        enc.write_int(index)
        enc.write_int(x)
        __builtin__.base.gamestatemanager.getState("RunningSession").send_message(enc.get_message())

    def upgrade(self, ind, x):
        old = self.units[ind]
        self.game.select_unit(self.build_unit(old.upgrades[x], old.unit_object.getPos()))
        self.destroy_unit(old)
            #unew.remove_node()

    def destroy_units(self):
        for u in self.units:
            u.remove_node()
        self.units = []

    def destroy_warpzones(self):
        for w in self.warpzones:
            w.remove_node()
        self.warpzones = []

    def destroy_unit(self, unit):
        self.units.remove(unit)
        unit.remove_node()

    def fight(self):
        self.unitcursor.unit_object.detachNode()

    def prepare(self):
        #self.unitcursor.reparentTo(__builtin__.render)
        return

    def prepare_cursor(self, name):
        if self.unitcursor is not None:
            self.unitcursor.remove_node()
        #if name == "warpzone":
         #   self.unitcursor = __builtin__.loader.loadModel("client/models/navi")
        self.unitcursor = database.units.create_client_unit(name)
        self.unitcursor.unit_object.setTransparency(TransparencyAttrib.MAlpha)
        self.unitcursor.reparentTo(__builtin__.render)
        self.unitcursor.set_destination(0, 0)

    def update_position(self, pos):
        for u in self.units:
            upos = pos[self.units.index(u)]
            u.setNextPos(Vec3(upos[0], upos[1], 0))

    def remove_cursor(self):
        self.unitcursor.detach_node()

